package com.zy.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zy.controllers.AuthRequest;
import com.zy.controllers.AuthResponse;
import com.zy.mapper.MyUserMapper;
import com.zy.model.MyUser;
import com.zy.restApi.FileUploadApi;
import com.zy.restApi.IdGeneratorApi;
import com.zy.utils.JwtTokenUtil;
import com.zy.web.bean.MyUserDTO;
import com.zy.web.bean.ResponseResult;
import lombok.extern.java.Log;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: shopping153_cloud
 * @description:
 * @author: zy
 * @create: 2025-08-29 14:31
 */
@Service
@Log
public class MyUserService extends ServiceImpl<MyUserMapper, MyUser> {

    private final PasswordEncoder passwordEncoder;   //spring security提供的密码的加密器
    private final JwtTokenUtil jwtTokenUtil;    // 生成和验证token的工具类
    private final IdGeneratorApi idGeneratorApi;
    private final FileUploadApi fileUploadApi;


    public MyUserService(PasswordEncoder passwordEncoder, JwtTokenUtil jwtTokenUtil, IdGeneratorApi idGeneratorApi, FileUploadApi fileUploadApi) {
        this.passwordEncoder = passwordEncoder;
        this.jwtTokenUtil = jwtTokenUtil;
        this.idGeneratorApi = idGeneratorApi;
        this.fileUploadApi = fileUploadApi;
    }

    /**
     * 根据用户ID查询用户信息。
     * @param id 用户ID
     * @return 用户DTO
     */
    public Optional<MyUserDTO> getUserById(Long id) {
        MyUser user = super.getById(id); // 使用 MyBatis Plus 的 selectById
        return Optional.ofNullable(user).map(this::convertToDto);
    }

    /**
     * 判断用户名是否存在。
     * @param username 用户名
     * @return 如果存在返回 true，否则返回 false
     */
    public boolean checkUsernameExists(String username) {
        QueryWrapper<MyUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userName", username);
        // 使用 MyBatis Plus 的 exists 方法
        return super.exists(   queryWrapper );
    }


    /**
     * 用户注册。
     * @param userDTO 注册信息
     * @return 注册成功的用户DTO
     * @throws IllegalArgumentException 如果用户名已存在
     */
    @Transactional
    public MyUserDTO registerUser(MyUserDTO userDTO) {
        if (checkUsernameExists(userDTO.getUserName())) { // 使用新的 checkUsernameExists
            throw new IllegalArgumentException("Registration failed: Username already exists: " + userDTO.getUserName());
        }

        //通过 feign客户端获得用户id
        ResponseResult rr = this.idGeneratorApi.getNextId();
        if (rr.getCode() != 1) {
            throw new RuntimeException("获取用户id失败");
        }
        if (userDTO.getAvatarFile() != null) {
            ResponseResult rr2 = this.fileUploadApi.upload(new MultipartFile[]{userDTO.getAvatarFile()});
            if (rr2.getCode() != 1) {
                throw new RuntimeException("上传头像失败");
            }
            List<String> avatarUrls = (List<String>) rr2.getData();
            userDTO.setAvatar(avatarUrls.get(0));
        }
        userDTO.setUserId( Long.parseLong( rr.getData().toString())   );
        userDTO.setUserPassword(    passwordEncoder.encode(userDTO.getUserPassword()) );
        userDTO.setUserStatus(   1 );

        MyUser user = new MyUser();
        BeanUtils.copyProperties(   userDTO, user );
        // 默认注册为普通用户，角色存储为逗号分隔的字符串
        user.setRoles("CUST"); // 默认角色
        super.save(user); // 使用 MyBatis Plus 的 insert 方法
        return convertToDto(user); // 返回转换后的DTO
    }

    /**
     * 将 User 实体转换为 UserDTO。
     */
    private MyUserDTO convertToDto(MyUser user) {
        MyUserDTO dto = new MyUserDTO();
        dto.setUserId(user.getUserId());
        dto.setUserName(user.getUserName());
        // 将逗号分隔的角色字符串转换为 Set<String>
        if (user.getRoles() != null && !user.getRoles().isEmpty()) {
            dto.setRoles(Arrays.stream(user.getRoles().split(","))
                    .map(String::trim)
                    .collect(Collectors.toSet()));
        } else {
            dto.setRoles(Collections.emptySet());
        }
        dto.setMobile(user.getMobile());
        dto.setEmail(user.getEmail());
        dto.setGender(user.getGender());
        dto.setAvatar(user.getAvatar());
        dto.setUserStatus(user.getUserStatus());
        // 不返回密码
        return dto;
    }


    /**
     * 用户登录。
     * @param authRequest 登录请求（用户名和密码）
     * @return 包含 JWT Token 和用户信息的响应
     * @throws IllegalArgumentException 如果用户名或密码不正确
     */
    public AuthResponse loginUser(AuthRequest authRequest) {
        QueryWrapper<MyUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userName", authRequest.getUserName());
        MyUser user = super.getOne(queryWrapper); // 使用 MyBatis Plus 的 selectOne

        if (user == null) {
            throw new IllegalArgumentException("Invalid username. ");
        }

        if (!passwordEncoder.matches(authRequest.getUserPassword(), user.getUserPassword())) {
            throw new IllegalArgumentException("Invalid  password.");
        }

        // 登录成功，生成 JWT Token
        // 将逗号分隔的角色字符串转换为 Set<String> 传递给 JWT 工具
        Set<String> rolesSet = Arrays.stream(user.getRoles().split(","))
                .map(String::trim)
                .collect(Collectors.toSet());

        String token = jwtTokenUtil.generateToken(user.getUserId(), user.getUserName(), rolesSet);


        return new AuthResponse(token, convertToDto(user));
    }

    /**
     * 获取所有用户信息 (仅限管理员)。
     * @return 用户DTO列表
     */
    public List<MyUserDTO> getAllUsers() {
        return super.list().stream() // 使用 MyBatis Plus 的 selectList
                .map(this::convertToDto)
                .collect(Collectors.toList());
    }


}
